namespace WP7Contrib.Communications
{
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Net;
    using System;

    public class UrlEncodedFormSerializer : ISerializer
    {
        public string ContentType { get { return "application/x-www-form-urlencoded"; } }

        public Stream Serialize(object graph)
        {
            var ms = new MemoryStream();

            if (graph != null)
            {
                var sw = new StreamWriter(ms);
                var type = graph.GetType();
                bool first = true;

                if (!type.IsPrimitive)
                {
                    var properties = type.GetProperties();
                    if (properties != null)
                    {
                        foreach (var p in properties)
                        {
                            var ignore = p.GetCustomAttributes(typeof(IgnoreDataMemberAttribute), true);
                            if (ignore == null || !ignore.Any())
                            {
                                string name = p.Name;
                                var attributes = p.GetCustomAttributes(typeof(DataMemberAttribute), true);
                                if (attributes != null && attributes.Any())
                                {
                                    var a = attributes[0] as DataMemberAttribute;
                                    if (a != null) name = a.Name;
                                }
                                var value = p.GetValue(graph, null);
                                if (value != null)
                                {
                                    sw.Write(
                                        "{0}{1}={2}",
                                        !first ? "&" : string.Empty,
                                        name,
                                        HttpUtility.UrlEncode(value.ToString()));
                                    first = false;
                                }
                            }
                        }
                    }
                }
                else
                {
                    // if the data is a .NET primitive, simply return it as string.
                    sw.Write(graph.ToString());
                }
                sw.Flush();
            }
            ms.Position = 0;
            return ms;
        }

        public T Deserialize<T>(Stream stream) where T : class
        {
            throw new NotImplementedException();
        }
    }
}
